package ro.src;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;


public class IO {

	public Settings s;
	public int config;
	public int samples;
	public int rows;
	public int columns;
	public Training tkb;
	
	public void readImage() {

	}
	
	public IO(Training k, Settings set){
		tkb = k;
		s = set;
	}

	public void readTrainData() throws IOException {
		
		RandomAccessFile train = new RandomAccessFile(s.trainData, "r");
		RandomAccessFile labels = new RandomAccessFile(s.trainLabels, "r");
		
		byte[] recordBuffer = new byte[28];
		ByteBuffer record = ByteBuffer.wrap(recordBuffer);
		record.order(ByteOrder.LITTLE_ENDIAN);
		
		//naglowek
		train.readInt(); //skip 32
		train.readInt(); //number of samples
		labels.readInt(); //skip 32
 
		train.seek(32);
		labels.seek(8);
		
		samples = train.readInt();
		rows = train.readInt();
		columns = train.readInt();
		
		if(tkb.getKnowledge(s.trainKB)){
			System.out.println("Training - Start");
			GUI.textInfo.append("Training - Start\n");
			int count = 0;
			while (train.getFilePointer() < train.length()-1000) {
				Image img = new Image(28);
				count++;
				int tmpL = labels.readUnsignedByte();
				for (int j = 0; j < 28; j++) {
					for (int i = 0; i < 28; i++) {
						int tmpPixel = train.readUnsignedByte();
						img.pixel[j][i] = tmpPixel;
						img.label = tmpL;
						//if(count==1) {
						//	if(tmpPixel>0) System.out.print(" ");
						//	else System.out.print("o");
						//}
					}
					//if(count==1) System.out.println();
				} 
				//policzenie cech
				tkb.addElement(img.extractFeatures());
				if(count%6000==0) {
					GUI.progress.setValue((int)(count/600));
				}
			}
			GUI.progress.setValue(100);
			System.out.println("Training - Done");
			GUI.textInfo.append("Training - Done\n");
			System.out.println(s.trainKB);
			GUI.textInfo.append(s.trainKB+"\n");
			tkb.writeKnowledge(s.trainKB);//zapis do pliku
			tkb.toString();
			train.close();
			labels.close();
		}
	}
	
public void readTestData() throws IOException {
		float wrong=0, correct=0;
		int rDigits[][]= new int[2][10];
		
		RandomAccessFile test = new RandomAccessFile(s.testData, "r");
		RandomAccessFile labels = new RandomAccessFile(s.testLabels, "r");
		
		byte[] recordBuffer = new byte[28];
		ByteBuffer record = ByteBuffer.wrap(recordBuffer);
		record.order(ByteOrder.LITTLE_ENDIAN);
		
		//naglowek
		test.readInt(); // skip 32
		test.readInt(); // number of samples
		labels.readInt(); // skip 32

		test.seek(32);
		labels.seek(8);
		
		samples = test.readInt();
		rows = test.readInt();
		columns = test.readInt();
		System.out.println("Test - Start");
		GUI.textInfo.append("Test - Start\n");
		System.out.println("Progress : Recognized");
		GUI.textInfo.append("Processing...\n");
		
		int count = 0;
		while (test.getFilePointer() < test.length()-1000) {
			Image img = new Image(28);
			count++;
			int tmpL = labels.readUnsignedByte();
			for (int j = 0; j < 28; j++) {
				for (int i = 0; i < 28; i++) {
					int tmpPixel = test.readUnsignedByte();
					img.pixel[j][i] = tmpPixel;
					img.label = tmpL;
					//if(count==1) {
					//	if(tmpPixel>0) System.out.print(" ");
					//	else System.out.print("#");
					//}
				}
				//if(count==1) System.out.println();
			} 
			//ekstrakcja cech
			Features f = img.extractFeatures();
			//knn
			int digit = tkb.findKNN(s.knn, f);
			//jezeli poprawnie
			if (digit==img.label) { correct++;
				rDigits[0][img.label]+=1;
				rDigits[1][img.label]+=1;}
			//jezeli nie
			else { wrong++; 
				rDigits[0][img.label]+=1;}
			//co 10% progress
			if(count%1000==0) {
				System.out.print(((float)count/(float)100) + "%");
				//GUI.textInfo.append(((float)count/(float)100) + "%");
				GUI.progress.setValue((int)(count/100));
				int tmp = (int)((correct/(correct+wrong))*10000);
				float result = (float)tmp/100;
				System.out.println(" \t : " + result + "%");
				//GUI.textInfo.append(" \t : " + result + "%\n");
				GUI.textResult.setText(result + "%");
			}
			
		}
		System.out.println("Test - Done");
		GUI.textInfo.append("Test - Done\n");
		GUI.progress.setValue(100);
		int tmp = (int)((correct/(correct+wrong))*10000);
		float finalResult = (float)tmp/100;
		System.out.println("Result: " + finalResult + "%");
		GUI.textResult.setText(finalResult + "%");
		
		System.out.println("0 : " + ((float)rDigits[1][0]/(float)rDigits[0][0])*100);
		System.out.println("1 : " + ((float)rDigits[1][1]/(float)rDigits[0][1])*100);
		System.out.println("2 : " + ((float)rDigits[1][2]/(float)rDigits[0][2])*100);
		System.out.println("3 : " + ((float)rDigits[1][3]/(float)rDigits[0][3])*100);
		System.out.println("4 : " + ((float)rDigits[1][4]/(float)rDigits[0][4])*100);
		System.out.println("5 : " + ((float)rDigits[1][5]/(float)rDigits[0][5])*100);
		System.out.println("6 : " + ((float)rDigits[1][6]/(float)rDigits[0][6])*100);
		System.out.println("7 : " + ((float)rDigits[1][7]/(float)rDigits[0][7])*100);
		System.out.println("8 : " + ((float)rDigits[1][8]/(float)rDigits[0][8])*100);
		System.out.println("9 : " + ((float)rDigits[1][9]/(float)rDigits[0][9])*100);
		GUI.textInfo.append("0: " + String.format("%.2f",((float)rDigits[1][0]/(float)rDigits[0][0])*100) + "%\n");
		GUI.textInfo.append("1: " + String.format("%.2f",((float)rDigits[1][1]/(float)rDigits[0][1])*100) + "%\n");
		GUI.textInfo.append("2: " + String.format("%.2f",((float)rDigits[1][2]/(float)rDigits[0][2])*100) + "%\n");
		GUI.textInfo.append("3: " + String.format("%.2f",((float)rDigits[1][3]/(float)rDigits[0][3])*100) + "%\n");
		GUI.textInfo.append("4: " + String.format("%.2f",((float)rDigits[1][4]/(float)rDigits[0][4])*100) + "%\n");
		GUI.textInfo.append("5: " + String.format("%.2f",((float)rDigits[1][5]/(float)rDigits[0][5])*100) + "%\n");
		GUI.textInfo.append("6: " + String.format("%.2f",((float)rDigits[1][6]/(float)rDigits[0][6])*100) + "%\n");
		GUI.textInfo.append("7: " + String.format("%.2f",((float)rDigits[1][7]/(float)rDigits[0][7])*100) + "%\n");
		GUI.textInfo.append("8: " + String.format("%.2f",((float)rDigits[1][8]/(float)rDigits[0][8])*100) + "%\n");
		GUI.textInfo.append("9: " + String.format("%.2f",((float)rDigits[1][9]/(float)rDigits[0][9])*100) + "%\n");
		
		test.close();
		labels.close();
	}

}
